from fastapi import APIRouter, Depends, HTTPException
from fastapi.security import OAuth2PasswordRequestForm
from tortoise.expressions import F
from pydantic import BaseModel, Field

from MyOAuth import generate_token, my_oauth2_scheme
from db.models.user import User
from passlib.context import CryptContext
from ApiResponse import ApiResponse, PageResult, DataDict
from typing import List
from tortoise.contrib.pydantic import pydantic_model_creator

# 创建路由
sys_user_router = APIRouter()

# 创建密码上下文
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

# 从Tortoise模型自动生成Pydantic响应模型
user_pydantic = pydantic_model_creator(
    User,
    name="User",
    include=("user_name", "nick_name", "avatar"),
    # 将可能为空的字段设为可选
    # optional=("create_time", "update_time", "cusname", "ename", "code",
    #           "connector", "telephone", "address", "level", "region",
    #           "channel", "isin", "statu", "owner", "paytype",
    #           "create_by", "update_by", "remark")
)


class LoginRequest(BaseModel):
    """登录请求模型"""
    username: str = Field(example="admin", description="用户名")
    password: str = Field(example="rootC2013", description="密码")


def verify_password(plain_password: str, hashed_password: str) -> bool:
    """验证密码"""
    try:
        return pwd_context.verify(plain_password, hashed_password)
    except Exception:
        return False


def hash_password(password: str) -> str:
    """加密密码（用于注册等场景）"""
    return pwd_context.hash(password)


@sys_user_router.post('/token', summary="给swagger用的")
async def login(loginForm: OAuth2PasswordRequestForm = Depends()):
    # 先根据用户名查找用户
    user = await User.filter(user_name=loginForm.username, del_flag__not="2").first()

    # 这个给swagger使用的接口不能return ApiResponse.error(500, "系统错误，请联系管理员") 因为前端处理的是Http请求header中的statusCode
    if not user:
        raise HTTPException(status_code=500, detail="账号不存在")

    # 验证密码
    if not verify_password(loginForm.password, user.password):
        raise HTTPException(status_code=500, detail="账号或密码不正确")

    # 检查用户状态
    if user.status != "0":
        raise HTTPException(status_code=500, detail="账号已被停用")

    # 生成token
    token: str = generate_token(user.user_id)

    return {"access_token": token, "token_type": "bearer"}


@sys_user_router.post('/login', summary="用户登录")
async def login(request: LoginRequest) -> ApiResponse[dict]:
    """
    用户登录接口

    参数:
    - username: 用户名
    - password: 密码
    """
    # 根据用户名查找用户
    user = await User.filter(user_name=request.username, del_flag__not="2").first()

    if not user:
        return ApiResponse.error(401, "账号不存在")

    # 验证密码
    if not verify_password(request.password, user.password):
        return ApiResponse.error(401, "账号或密码不正确")

    # 检查用户状态
    if user.status != "0":
        return ApiResponse.error(401, "账号已被停用")

    # 生成token
    token = generate_token(str(user.user_id))

    return ApiResponse.ok(data={"token": token}, msg="登录成功")


@sys_user_router.get('/getInfo', summary="获取用户信息接口")
async def login(jwt: dict = Depends(my_oauth2_scheme)) -> ApiResponse[user_pydantic]:
    user = await User.filter(user_id=jwt["id"]).first()
    if not user:
        return ApiResponse.error(401, f"id={jwt["id"]}不存在，请联系管理员")
    return ApiResponse.ok(data=user, msg="登录成功")


@sys_user_router.get('/dict', summary="获取用户列表")
async def get_user_list() -> ApiResponse[List[DataDict]]:
    # 查询所有活跃且未删除的用户
    result = await User.filter(status="0", del_flag__not="2").annotate(
        label=F("nick_name"),
        value=F("user_id")
    ).values("value", "label")
    return ApiResponse.ok(data=result, msg="用户列表查询成功")
